package com.example.myapplication;

import android.content.Context;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 更新服务类
 * 负责版本检查和下载功能
 * 支持断点续传和自动重试
 */
public class UpdateService {
    
    private static final String TAG = "UpdateService";
    private static final String BASE_URL = "http://101.37.91.4:32002/software/version/";
    private static final String DOWNLOAD_DIR = "updates";
    
    // 重试配置
    private static final int MAX_RETRY_COUNT = 3; // 最大重试次数
    private static final long RETRY_DELAY_MS = 2000; // 重试延迟（毫秒）
    private static final int CONNECT_TIMEOUT = 10000; // 连接超时
    private static final int READ_TIMEOUT = 30000; // 读取超时
    
    private Context context;
    private Gson gson;
    private OKHttpClass okHttpClass;
    
    public UpdateService(Context context) {
        this.context = context.getApplicationContext();
        this.gson = new Gson();
        this.okHttpClass = OKHttpClass.getInstance(context);
    }
    
    /**
     * 检查版本更新
     * @param deviceType 设备类型: "app", "firmware", "server"
     * @param callback 回调接口
     */
    public void checkVersion(String deviceType, VersionCheckCallback callback) {
        new Thread(() -> {
            try {
                String urlString = BASE_URL + deviceType;
                URL url = new URL(urlString);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(10000);
                connection.setReadTimeout(10000);
                
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = connection.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    reader.close();
                    
                    // 解析新的API响应格式
                    ApiResponse<VersionInfo> apiResponse = gson.fromJson(response.toString(), 
                            new TypeToken<ApiResponse<VersionInfo>>(){}.getType());
                    
                    if (apiResponse != null && apiResponse.isSuccess() && apiResponse.getData() != null) {
                        VersionInfo versionInfo = apiResponse.getData();
                        if (callback != null) {
                            callback.onSuccess(versionInfo);
                        }
                    } else {
                        // 兼容旧格式，直接解析VersionInfo
                        try {
                            VersionInfo versionInfo = gson.fromJson(response.toString(), VersionInfo.class);
                            if (callback != null) {
                                callback.onSuccess(versionInfo);
                            }
                        } catch (Exception e) {
                            String errorMsg = apiResponse != null ? apiResponse.getMsg() : "解析响应失败";
                            if (callback != null) {
                                callback.onError(errorMsg);
                            }
                        }
                    }
                } else {
                    if (callback != null) {
                        callback.onError("请求失败，状态码: " + responseCode);
                    }
                }
                connection.disconnect();
            } catch (Exception e) {
                Log.e(TAG, "检查版本失败", e);
                if (callback != null) {
                    callback.onError("网络错误: " + e.getMessage());
                }
            }
        }).start();
    }
    
    /**
     * 下载安装包（支持断点续传和自动重试）
     * @param versionInfo 版本信息
     * @param callback 下载回调
     */
    public void downloadFile(VersionInfo versionInfo, DownloadCallback callback) {
        downloadFileWithRetry(versionInfo, callback, 0);
    }
    
    /**
     * 带重试的下载方法（使用OkHttp，支持HTTPS和跳过证书验证）
     * @param versionInfo 版本信息
     * @param callback 下载回调
     * @param retryCount 当前重试次数
     */
    private void downloadFileWithRetry(VersionInfo versionInfo, DownloadCallback callback, int retryCount) {
        // 检查下载URL是否为空
        String downloadUrl = versionInfo.getDownloadUrl();
        if (downloadUrl == null || downloadUrl.isEmpty()) {
            if (callback != null) {
                callback.onError("下载地址为空");
            }
            return;
        }
        
        // 创建下载目录
        File externalFilesDir = context.getExternalFilesDir(null);
        if (externalFilesDir == null) {
            if (callback != null) {
                callback.onError("无法获取外部存储目录");
            }
            return;
        }
        
        File downloadDir = new File(externalFilesDir, DOWNLOAD_DIR);
        if (!downloadDir.exists()) {
            boolean created = downloadDir.mkdirs();
            if (!created) {
                Log.e(TAG, "创建下载目录失败: " + downloadDir.getAbsolutePath());
                if (callback != null) {
                    callback.onError("创建下载目录失败");
                }
                return;
            }
        }
        
        // 创建文件
        String fileName = getFileNameFromUrl(downloadUrl);
        if (fileName == null || fileName.isEmpty()) {
            fileName = "update_" + System.currentTimeMillis() + ".apk";
        }
        File file = new File(downloadDir, fileName);
        String filePath = file.getAbsolutePath();
        
        // 检查文件是否存在，如果存在则获取已下载大小（断点续传）
        long downloadedSize = 0;
        if (file.exists() && file.length() > 0) {
            downloadedSize = file.length();
            if (callback != null) {
                callback.onResume(downloadedSize);
            }
        }
        
        // 使用OkHttpClass下载文件（支持HTTPS和跳过证书验证）
        okHttpClass.downloadFile(downloadUrl, filePath, downloadedSize, new OKHttpClass.DownloadCallback() {
            @Override
            public void onProgress(int progress, long downloaded, long total) {
                if (callback != null) {
                    callback.onProgress(progress, downloaded, total);
                }
            }
            
            @Override
            public void onSuccess(String filePath) {
                if (callback != null) {
                    callback.onSuccess(filePath);
                }
            }
            
            @Override
            public void onError(String error) {
                // 网络错误，尝试重试
                Log.e(TAG, "下载失败 (重试 " + retryCount + "/" + MAX_RETRY_COUNT + "): " + error);
                
                if (retryCount < MAX_RETRY_COUNT) {
                    if (callback != null) {
                        callback.onRetry(retryCount + 1, MAX_RETRY_COUNT, error);
                    }
                    
                    // 等待后重试
                    new Thread(() -> {
                        try {
                            Thread.sleep(RETRY_DELAY_MS * (retryCount + 1)); // 递增延迟
                        } catch (InterruptedException ie) {
                            Thread.currentThread().interrupt();
                        }
                        
                        // 递归重试
                        downloadFileWithRetry(versionInfo, callback, retryCount + 1);
                    }).start();
                } else {
                    // 达到最大重试次数
                    if (callback != null) {
                        callback.onError("下载失败，已重试 " + MAX_RETRY_COUNT + " 次: " + error);
                    }
                }
            }
        });
    }
    
    
    /**
     * 从URL获取文件名
     */
    private String getFileNameFromUrl(String urlString) {
        if (urlString == null || urlString.isEmpty()) {
            Log.e(TAG, "URL为空，无法解析文件名");
            return null;
        }
        
        try {
            URL url = new URL(urlString);
            String path = url.getPath();
            if (path == null || path.isEmpty()) {
                Log.e(TAG, "URL路径为空: " + urlString);
                return null;
            }
            
            int lastSlash = path.lastIndexOf('/');
            if (lastSlash >= 0 && lastSlash < path.length() - 1) {
                String fileName = path.substring(lastSlash + 1);
                if (fileName != null && !fileName.isEmpty()) {
                    return fileName;
                }
            }
            
            // 如果无法从路径提取文件名，尝试从查询参数或使用默认名称
            Log.w(TAG, "无法从URL提取文件名: " + urlString);
        } catch (Exception e) {
            Log.e(TAG, "解析文件名失败: " + urlString, e);
        }
        return null;
    }
    
    /**
     * 版本检查回调接口
     */
    public interface VersionCheckCallback {
        void onSuccess(VersionInfo versionInfo);
        void onError(String error);
    }
    
    /**
     * 下载回调接口
     */
    public interface DownloadCallback {
        /**
         * 下载进度回调
         * @param progress 进度百分比 (0-100)
         * @param downloaded 已下载字节数
         * @param total 总字节数
         */
        void onProgress(int progress, long downloaded, long total);
        
        /**
         * 断点续传回调
         * @param downloadedSize 已下载大小
         */
        void onResume(long downloadedSize);
        
        /**
         * 重试回调
         * @param retryCount 当前重试次数
         * @param maxRetryCount 最大重试次数
         * @param error 错误信息
         */
        void onRetry(int retryCount, int maxRetryCount, String error);
        
        /**
         * 下载成功回调
         * @param filePath 文件路径
         */
        void onSuccess(String filePath);
        
        /**
         * 下载失败回调
         * @param error 错误信息
         */
        void onError(String error);
    }
}

